from decimal import Decimal

from sqlalchemy.dialects.mysql import DECIMAL
from sqlalchemy.ext.asyncio import AsyncSession
from typing import List

from sqlglot.expressions import Boolean

from exceptions.exception import ServiceException
from module_admin.entity.vo.common_vo import CrudResponseModel
from module_sale.dao.packaging_dao import PackagingDao
from module_sale.dao.price_dao import PriceDao
from module_sale.entity.vo.packaging_vo import PackagingPageQueryModel, PackagingModel
from module_sale.entity.vo.price_vo import DeletePriceModel, PriceModel, PricePageQueryModel, CalculatePriceQueryModel, \
    SalePriceDetailModel
from utils.common_util import CamelCaseUtil
from utils.excel_util import ExcelUtil


class PriceService:
    """
    每日采购价记录模块服务层
    """

    @classmethod
    async def get_price_list_services(
        cls, query_db: AsyncSession, query_object: PricePageQueryModel, is_page: bool = False
    ):
        """
        获取每日采购价记录列表信息service

        :param query_db: orm对象
        :param query_object: 查询参数对象
        :param is_page: 是否开启分页
        :return: 每日采购价记录列表信息对象
        """
        price_list_result = await PriceDao.get_price_list(query_db, query_object, is_page)

        return price_list_result


    @classmethod
    async def add_price_services(cls, query_db: AsyncSession, price_object: PriceModel):
        """
        新增每日采购价记录信息service

        :param query_db: orm对象
        :param price_object: 新增每日采购价记录对象
        :return: 新增每日采购价记录校验结果
        """
        try:
            await PriceDao.add_price_dao(query_db, price_object)
            await query_db.commit()
            return CrudResponseModel(is_success=True, message='新增成功')
        except Exception as e:
            await query_db.rollback()
            raise e

    @classmethod
    async def edit_price_services(cls, query_db: AsyncSession, price_object: PriceModel):
        """
        编辑每日采购价记录信息service

        :param query_db: orm对象
        :param price_object: 编辑每日采购价记录对象
        :return: 编辑每日采购价记录校验结果
        """
        edit_price = price_object.model_dump()
        price_info = await cls.price_detail_services(query_db, price_object.record_id)
        if price_info.record_id:
            try:
                await PriceDao.edit_price_dao(query_db, edit_price)
                await query_db.commit()
                return CrudResponseModel(is_success=True, message='更新成功')
            except Exception as e:
                await query_db.rollback()
                raise e
        else:
            raise ServiceException(message='每日采购价记录不存在')

    @classmethod
    async def delete_price_services(cls, query_db: AsyncSession, page_object: DeletePriceModel):
        """
        删除每日采购价记录信息service

        :param query_db: orm对象
        :param page_object: 删除每日采购价记录对象
        :return: 删除每日采购价记录校验结果
        """
        if page_object.record_ids:
            record_id_list = page_object.record_ids.split(',')
            try:
                for record_id in record_id_list:
                    await PriceDao.delete_price_dao(query_db, PriceModel(purchase_price_id=record_id))
                await query_db.commit()
                return CrudResponseModel(is_success=True, message='删除成功')
            except Exception as e:
                await query_db.rollback()
                raise e
        else:
            raise ServiceException(message='传入飞书记录ID为空')

    @classmethod
    async def price_detail_services(cls, query_db: AsyncSession, record_id: int):
        """
        获取每日采购价记录详细信息service

        :param query_db: orm对象
        :param record_id: 飞书记录ID
        :return: 飞书记录ID对应的信息
        """
        price = await PriceDao.get_price_detail_by_id(query_db, record_id=record_id)
        if price:
            result = PriceModel(**CamelCaseUtil.transform_result(price))
        else:
            result = PriceModel(**dict())

        return result

    @staticmethod
    async def export_price_list_services(price_list: List):
        """
        导出每日采购价记录信息service

        :param price_list: 每日采购价记录信息列表
        :return: 每日采购价记录信息对应excel的二进制数据
        """
        # 创建一个映射字典，将英文键映射到中文键
        mapping_dict = {
            'purchasePriceId': '每日收购价Id',
            'year': '数据年份',
            'createBy': '发布人',
            'createTime': '发布时间',
            'price': '收购单价',
            'purchaseDate': '收购日期',
            'updateBy': '更新人',
            'updateTime': '更新时间',
            'productSize': '产品规格',
            'planterName': '种植主体名称',
            'planterId': '种植主体id',
            'productAreaId': '产区id',
            'productArea': '产区',
        }
        binary_data = ExcelUtil.export_list2excel(price_list, mapping_dict)

        return binary_data


    @classmethod
    async def get_calculate_price_services(
            cls,
            query_db: AsyncSession,
            page_query: CalculatePriceQueryModel,
            is_page: bool = True
    ):
        """
            获取按照果价计算销售价格记录列表信息service

            :param query_db: orm对象
            :param page_query: 包装查询参数
            :param is_page: 是否开启分页
            :return: 按照果价计算销售价格记录对象列表
        """
        packaging_page_query = PackagingPageQueryModel(
            page_num = page_query.page_num,
            page_size = page_query.page_size,
            as_id=page_query.as_id,
            year=page_query.year,
            packaging_id=page_query.packaging_id
        )
        packaging_list = await PackagingDao.get_packaging_list(query_db, packaging_page_query, is_page)
        price_list = []
        for packaging in packaging_list.rows:
            packaging_obj = PackagingModel(** packaging)
            sale_price = SalePriceDetailModel()
            sale_price.packaging_id = packaging_obj.packaging_id
            sale_price.single_price = page_query.single_price
            sale_price.product_name = packaging_obj.product_name
            sale_price.year = packaging_obj.year
            sale_price.materials_cost = packaging_obj.materials_cost
            sale_price.chilling_fee = packaging_obj.chilling_fee
            sale_price.product_weight = packaging_obj.product_weight
            sale_price.product_id = packaging_obj.product_id
            sale_price.as_id = packaging_obj.as_id
            sale_price.fruit_total =  (page_query.single_price * sale_price.product_weight)
            sale_price.chilling_fee_total = (sale_price.chilling_fee * sale_price.product_weight)
            sale_price.total_price = (
                    (page_query.single_price * sale_price.product_weight)
                    + (sale_price.chilling_fee * sale_price.product_weight)
                    + sale_price.materials_cost )
            price_list.append(sale_price)
        price_list_result =  await PriceDao.get_calculate_sale_price_list(price_list, page_query.page_num, page_query.page_size)

        return price_list_result